package com.jrx.anytxn.param.job.bactchBillCompare.config;

import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.FileUtils;
import com.jrx.anytxn.param.config.BillCompareConfig;
import com.jrx.anytxn.param.config.PathFileConfig;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 核心对账-账务文件检查是否存在job
 *
 * @author : zcc
 * 2020/11/26
 */
@Configuration
@EnableConfigurationProperties(PathFileConfig.class)
public class BatchThirdBillFileCheckConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(BatchThirdBillFileCheckConfiguration.class);

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    private IOrganizationTableService organizationTableService;

    @Autowired
    private BillCompareConfig billCompareConfig;

    @Bean
    public Job thirdBillFileCheckJob() throws IOException {
        return jobBuilderFactory.get("thirdBillFileCheckJob")
                .start(thirdBillFileCheckStep())
                .build();
    }

    @Bean
    public Step thirdBillFileCheckStep() throws IOException {
        return stepBuilderFactory.get("thirdBillFileCheckStep").tasklet(thirdBillFileCheckTasklet()).build();
    }

    @Bean
    public Tasklet thirdBillFileCheckTasklet() {
        return (stepContribution, chunkContext) -> {
            PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(Constant.XIB_ORG_NUMBER);
            // 设置指定对账日期
            Date today = billCompareConfig.getToday();
            if (Objects.nonNull(today)) {
                org.setToday(today);
            }
            String fileDate = DateUtils.format(org.getToday(), DateUtils.DATE_PATTERN_ANOTHER);
            String businessDate = DateUtils.format(org.getToday());
            //  /data/file/xah
            String thirdChannel = billCompareConfig.getThirdChannel();
            String path = billCompareConfig.getFilePath() + File.separator + thirdChannel + File.separator + "transaction" + File.separator + fileDate;
            logger.info("交易流水文件检查开始，渠道号:{} 业务日期为:{} 路径为:{} ", thirdChannel, businessDate, path);

            Predicate<File> okFilter = file -> {
                String name = file.getName();
                boolean ok = (name.contains("transaction"));
                if (name.contains(thirdChannel) && ok && name.contains(fileDate) && name.contains(".ok")) {
                    return true;
                }
                return false;
            };

            Predicate<File> fileFilter = file -> {
                String name = file.getName();
                boolean fileName = (name.contains("transaction"));
                if (name.contains(thirdChannel) && fileName && name.contains(fileDate) && name.contains(".txt")) {
                    return true;
                }
                return false;
            };

            int i = 1;
            while (i <= billCompareConfig.getReadCount()) {

                List<File> files = FileUtils.findFiles(path);
                List<File> okList = files.stream().filter(okFilter).collect(Collectors.toList());
                logger.info("ok文件 业务日期为:{}  数量:{}", businessDate, okList.size());

                Integer size = null;
                if (CollectionUtils.isNotEmpty(okList)) {
                    size = Integer.parseInt(okList.get(0).getName().split("\\_", -1)[2]);
                    logger.info(" ok 文件 业务日期为:{}  应有数量:{}", businessDate, size);
                }

                List<File> fileList = files.stream().filter(fileFilter).collect(Collectors.toList());
                logger.info("date 文件 业务日期为:{}  实际数量:{}", businessDate, fileList.size());

                if (size != null && fileList.size() >= size) {
                    logger.info(" ok 文件验证通过 业务日期为:{} ", businessDate);
                    return RepeatStatus.FINISHED;
                }

                Thread.sleep(billCompareConfig.getReadPeriod());
                i++;
            }

            if (i > billCompareConfig.getReadCount()) {
                logger.error("渠道{}文件循环检查已超过{}次，检查作业将停止。业务日期为:{}", thirdChannel, billCompareConfig.getReadCount(), businessDate);
                // 检查无文件时不抛错，只打日志即可
                // throw new TxnBizException("文件循环检查已超最大次数，检查作业将停止。");
            }
            return RepeatStatus.FINISHED;
        };
    }
}